﻿#include "Window.h"

#define ClassName "TestGame"
#define MY_WS (WS_OVERLAPPED | \
				WS_CAPTION | \
				WS_SYSMENU | \
				WS_MINIMIZEBOX)

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	std::ostringstream oss;
	switch (msg)
	{
	case WM_MOUSEMOVE:
		oss << "*x=" << GET_X_LPARAM(lParam) 
			<< " y=" << GET_Y_LPARAM(lParam)
			<< std::endl;
		//OutputDebugStringA(oss.str().c_str());
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;

	case WM_KEYUP:
		if (wParam == VK_ESCAPE) PostQuitMessage(0);
		break;
	}

	return DefWindowProc(hWnd, msg, wParam, lParam);
}


Window::Window(int width, int height, LPCSTR WindowName)
	:
	hInstance(GetModuleHandle(NULL))
{
	// 1.定义窗口类
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(wcex);//指定结构体的大小
	wcex.style = CS_CLASSDC;//结构体的大小，‌用于版本控制。‌
	wcex.lpfnWndProc = MsgProc;//指向窗口过程的指针，‌处理窗口的各种消息。‌
	wcex.cbClsExtra = 0;//窗口类附加内存的大小，‌通常设为0。‌
	wcex.cbWndExtra = 0;//窗口附加内存的大小，‌通常设为0。‌
	wcex.hInstance = hInstance;//应用程序实例句柄
	wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);//窗口类的光标句柄
	wcex.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(0, 0, 0));//窗口背景画刷句柄
	wcex.lpszMenuName = nullptr;//窗口类的菜单
	wcex.lpszClassName = ClassName;//窗口类名
	wcex.hIcon = nullptr;//类图标的句柄
	wcex.hIconSm = nullptr;//小图标的句柄

	// 2.注册窗口类
	RegisterClassEx(&wcex);//注册本地窗口

	RECT rect;
	rect.left = rect.top = 0;
	rect.right = width;
	rect.bottom = height;
	AdjustWindowRect(&rect, MY_WS, FALSE);//根据所需的客户端矩形大小计算窗口矩形的所需大小
	// 获取显示器宽和高
	int cx = GetSystemMetrics(SM_CXSCREEN);
	int cy = GetSystemMetrics(SM_CYSCREEN);
	// 3.创建窗口
	_hWnd = CreateWindowEx(
		0,//扩展窗口样式
		ClassName,//窗口类名或窗口类原子的指针
		WindowName,//窗口名
		MY_WS,//窗口样式
		(cx - width) / 2,//显示窗口位置
		(cy - height) / 2,
		rect.right - rect.left,//创建窗口大小
		rect.bottom - rect.top,
		HWND_DESKTOP,//没有父窗口
		nullptr,//菜单句柄或子窗口ID
		hInstance,//应用程序实例句柄
		this//指向窗口创建数据的指针
	);

	if (nullptr == _hWnd)
		throw std::runtime_error("CreateWindowEx error");
	// 4.显示窗口
	ShowWindow(_hWnd, SW_SHOW);//设置指定窗口的显示状态
	UpdateWindow(_hWnd);
	// 创建Direct3D
	_gfx = std::make_unique<Graphics>(_hWnd, width, height);
}

Window::~Window() 
{
	// 取消对窗口类的注册
	UnregisterClass(ClassName, hInstance);
}

BOOL Window::Message() noexcept
{
	MSG msg{ 0 };
	while (PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) 
	{
		// 窗口退出信息
		if (msg.message == WM_QUIT)
		{
			return FALSE;
		}
		TranslateMessage(&msg);// 对相关消息进行一些转换
		DispatchMessage(&msg);// 将转换后的消息发送给消息过程函数
	}
	return TRUE;
}

Graphics& Window::Gfx()
{
	return *_gfx;
}

HWND Window::hWnd()
{
	return _hWnd;
}
